using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web;
using Rest;
using Rest.Transport;

namespace Rest.Http
{
    /// <summary>
    /// Represents the encoding to use for REST request message body
    /// TODO: Rename this class, I don't think the name makes sense.
    /// </summary>
    public abstract class HttpContentType
    {
        /// <summary>
        /// Atom form encoding
        /// </summary>
        public static HttpContentType Atom
        {
            get { return new Atom(); }
        }

        /// <summary>
        /// Multipart form encoding
        /// </summary>
        public static HttpContentType MultipartFormData
        {
            get { return new MultipartFormData(); }
        }

        /// <summary>
        /// Url encoding
        /// </summary>
        public static HttpContentType FormUrlEncoded
        {
            get { return new FormUrlEncoded(); }
        }

        /// <summary>
        /// Represents the media type of the current instance. Corresponds to the
        /// Content-type HTTP header.
        /// </summary>
        /// <example>application/x-www-form-urlencoded</example>
        public abstract String ContentType { get; set; }

        /// <summary>
        /// Creates request body
        /// </summary>
        /// <param name="parameters"></param>
        /// <param name="dataItems"></param>
        /// <param name="characterEncoding"></param>
        /// <returns></returns>
        public Byte[] CreateRequestBody(
            RestParameterCollection parameters,
            RestDataItemCollection dataItems,
            Encoding characterEncoding)
        {
            using (MemoryStream memStream = new MemoryStream())
            {
                WriteRequestBody(memStream, parameters, dataItems,
                    characterEncoding);

                return memStream.ToArray();
            }
        }

        /// <summary>
        /// Writes the supplied data to the stream. The supplied stream should
        /// not be closed by the implementation of this method.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="parameters"></param>
        /// <param name="dataItems"></param>
        /// <param name="characterEncoding"></param>
        public abstract void WriteRequestBody(
            Stream stream, 
            RestParameterCollection parameters,
            RestDataItemCollection dataItems,
            Encoding characterEncoding);
    }
}
